
from new import classobj

class Feature:
  '''Base class for features occupying a genomic interval.'''
  def __init__(self, chr, spos, epos, content=None):
      self.chr = chr
      self.spos = long(spos)
      self.epos = long(epos)
      self.content = content

  def getDetails(self):
    return self


class FeatureParser:
  '''Abstract base class for feature parsers (from strings).'''

  def parse(self, line):
    '''Return the parsed feature, or None if the line is empty or a comment.'''
    raise Exception("unknown feature type")

  def getIndexContext(self):
    return ""   # default featureparser doesn't need context: each feature defines its own interval

  def getLastIndexContext(self):
    return ""   # default featureparser doesn't need context: each feature defines its own interval

  def setIndexContext(self, context):
    pass
  
  def getMaxFeatureSize(self):
    '''Return the maximum possible feature length, or None if unlimited.'''
    return None

  def getFeatureType(self):
    '''Return a string ID for the feature type.'''
    return None

_featureParsers = {}

def registerFeatureParserClass(name, cls):
  '''Register a filename suffix as corresponding to a particular type of FeatureParser.'''
  if isinstance(cls, FeatureParser):
    _featureParsers[name] = type(cls)
  elif isinstance(cls, classobj) and isinstance(cls(), FeatureParser):
    _featureParsers[name] = cls
  else:
    raise Exception("Argument cls should be an instance of FeatureParser or a derived type -- type is", type(cls))

def createFeatureParser(filename):
  '''Factory method for feature parsers.'''
  for (name, ParserClass) in _featureParsers.items():
    if filename == name or filename.endswith(".%s" % name) or filename.endswith(".%s.txt" % name) or filename.endswith(".%s.INDEX" % name):
      return ParserClass()
  raise Exception("Can't determine type of file " + filename)

